package com.jt.www.job.commission;

import com.alibaba.fastjson.JSON;
import com.jt.www.dao.mapper.market.CommissionPushMapper;
import com.jt.www.domain.dto.CommissionPushDTO;
import com.jt.www.domain.enums.common.IsDeletedEnum;
import com.jt.www.domain.enums.common.PushStatusEnum;
import com.jt.www.domain.po.CommissionPush;
import com.jt.www.domain.vo.SaleResultVO;
import com.jt.www.enums.ResultEnum;
import com.jt.www.remote.JtsaleappClient;
import com.jt.www.util.JsonUtils;
import com.jt.www.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.util.Date;
import java.util.List;

/**
 * 佣金推送至销管
 *
 * @author shaoyn
 * @create 2020-04-14
 */
@Component
@EnableScheduling
public class CommissionPushTask implements SchedulingConfigurer {

    public static final Logger log = LoggerFactory.getLogger(CommissionPushTask.class);
    /**
     * 协议缓存key-控制多个服务器间割时间长发布问题
     */
    private static final String COMMISSION_PUSH_LOCK_KEY = "EDU_COMMISSION_PUSH";
    /**
     * 协议缓存key-控制多个任务同时触发问题
     */
    private static final String COMMISSION_PUSH_JOB_LOCK_KEY = "EDU_COMMISSION_PUSH_JOB";
    //时间间隔
    private static final long TIME_OUT = 60L;
    @Autowired
    CommissionPushMapper commissionPushMapper;
    @Autowired
    JtsaleappClient jtsaleappClient;
    /**
     * 任务开关
     */
    @Value("${jtpf.commission.open}")
    private int checkOpen;
    /**
     * 任务执行周期
     */
    @Value("${jtpf.commission.cron}")
    private String cron;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        if (checkOpen != 1) {
            return;
        }
        if (RedisUtil.setOneHoursLock(COMMISSION_PUSH_LOCK_KEY)) {
            Runnable task0 = () -> checkStart();
            Trigger trigger0 = triggerContext -> new CronTrigger(cron).nextExecutionTime(triggerContext);
            taskRegistrar.addTriggerTask(task0, trigger0);
        }
    }

    private void checkStart() {
        //在定时里面也加重复执行校验
        if (RedisUtil.setLock(COMMISSION_PUSH_JOB_LOCK_KEY, "1", TIME_OUT)) {
            log.info("佣金推送开始执行");
            Weekend<CommissionPush> weekend = Weekend.of(CommissionPush.class);
            WeekendCriteria<CommissionPush, Object> Criteria = weekend.weekendCriteria();
            Criteria.andLessThanOrEqualTo(CommissionPush::getTimes, 5);
            Criteria.andNotEqualTo(CommissionPush::getPushStatus, PushStatusEnum.SUCCESS.getCode());
            Criteria.andEqualTo(CommissionPush::getIsDeleted, IsDeletedEnum.NO.getValue());

            //所有未推送及推送失败(次数小于5)
            List<CommissionPush> commissionPushes = commissionPushMapper.selectByExample(weekend);
            for (CommissionPush commissionPush : commissionPushes) {
                //每一条做个判断
                String redisKey = RedisUtil.createLockKey(COMMISSION_PUSH_LOCK_KEY, String.valueOf(commissionPush.getId()),
                        String.valueOf(commissionPush.getTimes()));

                //查看当前缓存中是否有该佣金推送 当前次数的处理
                if (RedisUtil.setLock(redisKey, "1", TIME_OUT)) {
                    CommissionPushDTO commissionPushDTO = new CommissionPushDTO(commissionPush);
                    SaleResultVO saleResultVO = null;
                    try {
                        String resultVO = jtsaleappClient.pushSale(commissionPushDTO);
                        saleResultVO = JsonUtils.fromJson(resultVO, SaleResultVO.class);
                    } catch (Exception e) {
                        log.info("全面营销渠道保单推送私保接口调用失败!入参：\n{}", JSON.toJSONString(commissionPushDTO));
                        e.printStackTrace();
                    }
                    //失败
                    if (null == saleResultVO || saleResultVO.getRc().equals(ResultEnum.ERROR_CODE_9999)) {
                        commissionPush.setTimes(commissionPush.getTimes() + 1);
                        commissionPush.setPushStatus(PushStatusEnum.ERROR.getCode());
                        commissionPush.setErrorMsg(null == saleResultVO ? "接口调用失败" : saleResultVO.getMsg());
                    } else {
                        commissionPush.setPushStatus(PushStatusEnum.SUCCESS.getCode());
                    }
                    commissionPush.setUpdateTime(new Date());
                    commissionPushMapper.updateByPrimaryKeySelective(commissionPush);
                }
            }
            log.info("佣金推送执行结束");
        }
    }

}
